package com.weilive.api.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.weilive.api.ServerConfig;
import com.weilive.api.dao.model.AdvanceVideo;
import com.weilive.api.dao.model.BannerAds;
import com.weilive.api.dao.model.MainView;
import com.weilive.api.dao.model.UserInfo;
import com.weilive.api.dao.model.VjLevel;
import com.weilive.api.dao.model.VjSubType;
import com.weilive.api.dao.model.VjType;
import com.weilive.api.gate.json.protocol.AdModel;
import com.weilive.api.gate.json.protocol.AdvanceVideoModel;
import com.weilive.api.gate.json.protocol.RoomInfoModel;
import com.weilive.api.gate.json.protocol.VjSubTypeModel;
import com.weilive.api.gate.json.protocol.VjTypeModel;
import com.weilive.core.cache.redis.Order;
import com.weilive.core.cache.redis.RedisConfig;
import com.weilive.core.cache.redis.RedisService;
import com.weilive.core.common.SharedTimer;
import com.weilive.core.utils.DateUtil;
import com.weilive.core.utils.Utils;

/**
 * 
 * 2级数据缓存池
 * 
 * @author houzhiwei
 *
 */
@Service
public class DataPool {
	private static final Logger logger = LoggerFactory.getLogger(DataPool.class);
	private final int TYPE_DOREN = -1;
	private final int TYPE_ALL = -2;
	// 直播呈现规则: 直播人数->人工推荐->最近直播
	// 发现呈现规则: 人工推荐->最近直播
	@Autowired
	private RedisService redis;
	@Autowired
	private ResourceSystem resourceSystem;// 资源类
	@Autowired
	private UserSystem userSystem;

	private Map<Integer, List<RoomInfoModel>> discoverByVjTypeList = new HashMap<Integer, List<RoomInfoModel>>();// 发现列表:max=240,需要自己分页
	private Map<Integer, List<RoomInfoModel>> liveByVjTypeList = new HashMap<Integer, List<RoomInfoModel>>();// 分类列表:max=100
	// -------------------------预告数据-------------------------
	private List<AdvanceVideoModel> videoList = new ArrayList<AdvanceVideoModel>();
	// -------------------------首页推荐-------------------------
	private List<RoomInfoModel> dorenList = new ArrayList<RoomInfoModel>();// 首页达人list
	private List<AdModel> adList = new ArrayList<AdModel>();// 首页广告列表
	private List<VjTypeModel> vjTypeList = new ArrayList<VjTypeModel>();// 首页vj列表
	// -------------------------发现 和首页推荐-------------------------
	private LinkedHashMap<Integer, List<RoomInfoModel>> discoverShowList = new LinkedHashMap<Integer, List<RoomInfoModel>>();// 发现推荐
	private LinkedHashMap<String, List<RoomInfoModel>> liveShowList = new LinkedHashMap<String, List<RoomInfoModel>>();// 首页推荐视频
	private List<RoomInfoModel> liveList = new ArrayList<RoomInfoModel>();// 首页直播列表
	// 缓存数据
	private Map<String, RoomInfoModel> users = new HashMap<String, RoomInfoModel>();// 所有用户数据缓存
	private Map<String, String> roomCount = new HashMap<String, String>();// 房间人数

	@PostConstruct
	public void init() {
		createData();

		SharedTimer.schedule(new Runnable() {

			@Override
			public void run() {
				// 制造数据
				createData();
			}
		}, ServerConfig.getTimerPeriod() * 1000L, ServerConfig.getTimerPeriod() * 1000L);

		logger.info("--------数据池 初始化数据成功--------!");
	}

	/**
	 * 制造数据
	 * 
	 */
	private void createData() {
		long begin = System.currentTimeMillis();
		try {

			String roomCountStr = redis.get(RedisConfig.USER_ROOM_COUNT);
			this.setRoomCount(roomCountStr);

			Map<String, RoomInfoModel> users = new HashMap<String, RoomInfoModel>();// 所有用户数据缓存
			// -------------------------资源数据-------------------------
			List<VjType> c_vjType = resourceSystem.getVjTypeConfigList();// vj
			List<AdvanceVideo> c_video = resourceSystem.getAdvanceConfigList();// 预告资源
			List<BannerAds> c_adslist = resourceSystem.getBannerAdsConfigList();// 广告资源
			Map<Integer, List<MainView>> c_views = resourceSystem.getMainViewConfigMap();// 主页人工推荐
			Map<Integer, List<MainView>> c_discovers = resourceSystem.getDiscoverConfigMap();// 发现人工推荐
			// -------------------------分类数据-------------------------
			Map<Integer, List<RoomInfoModel>> discoverByVjTypeList = new HashMap<Integer, List<RoomInfoModel>>();// 发现列表:max=240,需要自己分页
			Map<Integer, List<RoomInfoModel>> liveByVjTypeList = new HashMap<Integer, List<RoomInfoModel>>();// 分类列表:max=100
			// -------------------------预告数据-------------------------
			List<AdvanceVideoModel> videoList = new ArrayList<AdvanceVideoModel>();
			// -------------------------首页推荐-------------------------
			List<RoomInfoModel> dorenList = new ArrayList<RoomInfoModel>();// 首页达人list
			List<AdModel> adList = new ArrayList<AdModel>();// 首页广告列表
			List<VjTypeModel> vjTypeList = new ArrayList<VjTypeModel>();// 首页vj列表
			// -------------------------发现 和首页推荐-------------------------
			LinkedHashMap<Integer, List<RoomInfoModel>> discoverShowList = new LinkedHashMap<Integer, List<RoomInfoModel>>();// 发现推荐
			LinkedHashMap<String, List<RoomInfoModel>> liveShowList = new LinkedHashMap<String, List<RoomInfoModel>>();// 首页推荐视频

			List<RoomInfoModel> liveList = new ArrayList<RoomInfoModel>();// 首页直播列表

			final int DISCOVER_MAX_COUNT = ServerConfig.getDiscoverMaxcount();
			final int LIVE_MAX_COUNT = ServerConfig.getLiveMaxcount();
			for (VjType vjType : c_vjType) {
				// 直播的找100个
				final String liveByVjTypeKey = RedisConfig.LIVE_USER_BY_VJ_TYPE_ID + vjType.getVjTypeId();// 直播的
				// 找出前240个
				final String endByVjTypeKey = RedisConfig.LIVE_END_BY_VJ_TYPE + vjType.getVjTypeId();// 结束的

				final List<String> liveUserByVjType = redis.zrange(liveByVjTypeKey, 0, LIVE_MAX_COUNT - 1, Order.DESC);// 按人数
				final List<String> endUserByVjType = redis.zrange(endByVjTypeKey, 0, DISCOVER_MAX_COUNT - 1,
						Order.DESC);// 按时间

				// 数据组合
				createDiscoverDataByVjType(vjType.getVjTypeId(), endUserByVjType, users, discoverByVjTypeList,
						c_discovers.get(vjType.getVjTypeId()));
				createDiscoverShowDataByVjType(vjType.getVjTypeId(), endUserByVjType, users, discoverShowList,
						c_discovers.get(vjType.getVjTypeId()));
				createLiveDataByVjType(vjType.getVjTypeId(), liveUserByVjType, endUserByVjType, users, liveByVjTypeList,
						c_views.get(vjType.getVjTypeId()));
				createLiveShowDataByVjType(vjType.getVjTypeId() + ":" + vjType.getVjTypeName(), liveUserByVjType,
						endUserByVjType, users, liveShowList, c_views.get(vjType.getVjTypeId()));

			}
			// 直播的找出前100个
			final String liveKey = RedisConfig.LIVE_USER;// 所有正在直播的
			// 结束的找出前100个
			final String endKey = RedisConfig.LIVE_END;// 所有已经结束的
			final List<String> liveUser = redis.zrange(liveKey, 0, LIVE_MAX_COUNT - 1, Order.DESC);// 直播的按人数
			final List<String> endUser = redis.zrange(endKey, 0, LIVE_MAX_COUNT - 1, Order.DESC);// 结束的按时间

			// 构造首页直播数据
			createLiveListData(liveUser, endUser, users, liveList, c_views.get(TYPE_ALL));
			// 构造达人数据
			createDorenData(dorenList, users, c_views.get(TYPE_DOREN));
			// 构造预告数据
			createVideoData(videoList, users, c_video);
			createAdListData(adList, c_adslist);
			createVjTypeData(vjTypeList, c_vjType);

			this.setDiscoverByVjTypeList(discoverByVjTypeList);
			this.setLiveByVjTypeList(liveByVjTypeList);
			this.setVideoList(videoList);
			this.setDorenList(dorenList);
			this.setAdList(adList);
			this.setVjTypeList(vjTypeList);
			this.setDiscoverShowList(discoverShowList);
			this.setLiveShowList(liveShowList);
			this.setLiveList(liveList);
			this.setUsers(users);
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info("DataPool数据获取成功!耗时={}ms", (System.currentTimeMillis() - begin));
	}

	private void createAdListData(List<AdModel> adList, List<BannerAds> configs) {

		for (BannerAds v : configs) {
			AdModel model = new AdModel();
			model.setBanner_ads_id(v.getBannerAdsId());
			model.setBanner_ads_type_id(v.getBannerAdsTypeId());
			model.setBanner_pic(v.getBannerPic());
			model.setContent_pic(v.getContentPic());
			model.setIs_active_flag(v.getIsActiveFlag());
			model.setContent(v.getContent());

			adList.add(model);
		}
	}

	private void createVjTypeData(List<VjTypeModel> vjTypeList, List<VjType> configs) {

		for (VjType config : configs) {
			VjTypeModel vjType = new VjTypeModel();
			vjType.setVjTypeId(config.getVjTypeId());
			vjType.setVjTypeName(config.getVjTypeName());
			vjType.setIsActiveFlag(config.getIsActiveFlag());
			vjType.setCreatedTime(DateUtil.dateFormat(config.getCreatedTime()));
			vjType.setUpdatedTime(DateUtil.dateFormat(config.getUpdatedTime()));

			List<VjSubTypeModel> subList = new ArrayList<VjSubTypeModel>();
			for (VjSubType subConfig : config.getVjSubTypeList()) {
				VjSubTypeModel vjSubType = new VjSubTypeModel();
				vjSubType.setVjTypeId(subConfig.getVjTypeId());
				vjSubType.setVjSubtypeId(subConfig.getVjSubTypeId());
				vjSubType.setVjSubtypeName(subConfig.getVjSubTypeName());
				vjSubType.setIsActiveFlag(subConfig.getIsActiveFlag());
				vjSubType.setCreatedTime(DateUtil.dateFormat(subConfig.getCreatedTime()));
				vjSubType.setUpdatedTime(DateUtil.dateFormat(subConfig.getUpdatedTime()));

				subList.add(vjSubType);
			}
			vjType.setVjSubTypeList(subList);
			vjTypeList.add(vjType);
		}
	}

	private void createDorenData(List<RoomInfoModel> dorenList, Map<String, RoomInfoModel> users,
			List<MainView> configs) {
		Set<String> sameUserId = new HashSet<String>();

		final int SHOW_MAX_COUNT = ServerConfig.getDorenShowMaxcount();
		if (configs != null) {
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				// 达人
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);

				if (roomInfo != null) {
					dorenList.add(roomInfo);
				}
				// 优先人工推荐的
				sameUserId.add(String.valueOf(config.getUserId()));
				if (dorenList.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}

		if (dorenList.size() < SHOW_MAX_COUNT) {
			// 随机选择
			List<String> userList = redis.zrange(RedisConfig.LIVE_END, 0, 11, Order.DESC);
			// 在按顺序选择
			for (String userId : userList) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				// 达人
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					dorenList.add(roomInfo);
				}
				sameUserId.add(userId);
				if (dorenList.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
	}

	private void createVideoData(List<AdvanceVideoModel> videoList, Map<String, RoomInfoModel> users,
			List<AdvanceVideo> configs) {

		Set<Long> sameUserId = new HashSet<Long>();
		final int timeExpire = ServerConfig.getVideoTimeExpire();
		for (AdvanceVideo v : configs) {
			// 过期了就不显示了
			if (DateUtil.isExpired(v.getStartTime(), timeExpire)) {
				continue;
			}
			if (sameUserId.contains(v.getUserId())) {
				// 去重
				continue;
			}

			RoomInfoModel roomInfo = getNewRoomInfo(v.getUserId(), users);
			if (roomInfo != null) {
				AdvanceVideoModel video = new AdvanceVideoModel();
				video.setContent(v.getContent());
				video.setPic(v.getPic());
				video.setTitle(v.getTitle());
				video.setStartedTime(DateUtil.dateFormat(v.getStartTime()));
				video.setUserInfo(roomInfo);
				videoList.add(video);
			}
			sameUserId.add(v.getUserId());
		}
	}

	/**
	 * 构建发现分类数据
	 * 
	 * @param vjTypeId
	 * @param endUserByVjType
	 * @param users
	 * @param discoverList
	 * @param configs
	 */
	private void createDiscoverDataByVjType(int vjTypeId, List<String> endUserByVjType,
			Map<String, RoomInfoModel> users, Map<Integer, List<RoomInfoModel>> discoverByVjTypeList,
			List<MainView> configs) {
		if (vjTypeId == 0) {
			return;
		}
		List<RoomInfoModel> roomInfos = new ArrayList<RoomInfoModel>();
		discoverByVjTypeList.put(vjTypeId, roomInfos);// 放入map
		final int SHOW_MAX_COUNT = ServerConfig.getDiscoverMaxcount();
		Set<String> sameUserId = new HashSet<String>();

		if (configs != null) {
			// 首先推荐的数据放最前面
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				// 加入重复队列
				sameUserId.add(String.valueOf(config.getUserId()));

				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}

		if (roomInfos.size() < SHOW_MAX_COUNT) {
			for (String userId : endUserByVjType) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				// 加入重复队列
				sameUserId.add(userId);
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
	}

	/**
	 * 构建发现推荐数据
	 * 
	 * @param vjTypeId
	 * @param endUserByVjType
	 * @param users
	 * @param discoverShowList
	 * @param configs
	 */
	private void createDiscoverShowDataByVjType(int vjTypeId, List<String> endUserByVjType,
			Map<String, RoomInfoModel> users, LinkedHashMap<Integer, List<RoomInfoModel>> discoverShowList,
			List<MainView> configs) {
		if (vjTypeId == 0) {
			return;
		}
		List<RoomInfoModel> roomInfos = new ArrayList<RoomInfoModel>();
		discoverShowList.put(vjTypeId, roomInfos);// 放入map

		final int SHOW_MAX_COUNT = ServerConfig.getDiscoverShowMaxcount();
		Set<String> sameUserId = new HashSet<String>();
		// 首先推荐的数据放最前面
		if (configs != null) {
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				// 加入重复队列
				sameUserId.add(String.valueOf(config.getUserId()));
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
		// 人数不够
		if (roomInfos.size() < SHOW_MAX_COUNT) {
			// 寻找序列最高的
			for (String userId : endUserByVjType) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				// 加入重复队列
				sameUserId.add(userId);
				// 达到最大退出
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
	}

	/**
	 * 构建分类数据
	 * 
	 * @param vjTypeId
	 * @param liveUserByVjType
	 * @param endUserByVjType
	 * @param users
	 * @param liveByVjTypeList
	 * @param configs
	 */
	private void createLiveDataByVjType(int vjTypeId, List<String> liveUserByVjType, List<String> endUserByVjType,
			Map<String, RoomInfoModel> users, Map<Integer, List<RoomInfoModel>> liveByVjTypeList,
			List<MainView> configs) {
		List<RoomInfoModel> roomInfos = new ArrayList<RoomInfoModel>();
		liveByVjTypeList.put(vjTypeId, roomInfos);// 放入map
		Set<String> sameUserId = new HashSet<String>();

		final int SHOW_MAX_COUNT = ServerConfig.getLiveMaxcount();
		// 优先直播的
		for (String userId : liveUserByVjType) {
			if (sameUserId.contains(userId)) {
				continue;
			}
			RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
			if (roomInfo != null) {
				roomInfos.add(roomInfo);
			}
			sameUserId.add(userId);
			if (roomInfos.size() == SHOW_MAX_COUNT) {
				break;
			}
		}
		// 不够取推荐的
		if (roomInfos.size() < SHOW_MAX_COUNT && configs != null) {
			// 取推荐的
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				sameUserId.add(String.valueOf(config.getUserId()));
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
		// 不够取结束的
		if (roomInfos.size() < SHOW_MAX_COUNT) {
			// 取推荐的
			for (String userId : endUserByVjType) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				sameUserId.add(userId);
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
	}

	/**
	 * 构建首页推荐数据数据
	 * 
	 * @param vjTypeId(vj类型
	 *            + 名字)
	 * @param liveUserByVjType(正在直播中的用户)
	 * @param endUserByVjType(直播过的用户)
	 * @param users(缓存用户)
	 * @param liveShowList(show数据)
	 * @param configs(资源数据)
	 */
	private void createLiveShowDataByVjType(String vjTypeId, List<String> liveUserByVjType,
			List<String> endUserByVjType, Map<String, RoomInfoModel> users,
			Map<String, List<RoomInfoModel>> liveShowList, List<MainView> configs) {
		if (vjTypeId.startsWith("0")) {
			return;
		}
		List<RoomInfoModel> roomInfos = new ArrayList<RoomInfoModel>();
		liveShowList.put(vjTypeId, roomInfos);// 放入map
		Set<String> sameUserId = new HashSet<String>();

		final int SHOW_MAX_COUNT = ServerConfig.getLiveShowMaxcount();
		// 优先直播的
		for (String userId : liveUserByVjType) {
			if (sameUserId.contains(userId)) {
				continue;
			}
			RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
			if (roomInfo != null) {
				roomInfos.add(roomInfo);
			}
			sameUserId.add(userId);
			if (roomInfos.size() == SHOW_MAX_COUNT) {
				break;
			}
		}
		// 不够取推荐的
		if (roomInfos.size() < SHOW_MAX_COUNT && configs != null) {
			// 取推荐的
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				sameUserId.add(String.valueOf(config.getUserId()));
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
		// 不够取结束的
		if (roomInfos.size() < SHOW_MAX_COUNT) {
			// 取推荐的
			for (String userId : endUserByVjType) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					roomInfos.add(roomInfo);
				}
				sameUserId.add(userId);
				if (roomInfos.size() == SHOW_MAX_COUNT) {
					break;
				}
			}
		}
	}

	/**
	 * 构造首页显示数据
	 * 
	 * @param liveUsers
	 * @param endUsers
	 * @param users
	 * @param liveList
	 * @param configs
	 */
	private void createLiveListData(List<String> liveUsers, List<String> endUsers, Map<String, RoomInfoModel> users,
			List<RoomInfoModel> liveList, List<MainView> configs) {

		Set<String> sameUserId = new HashSet<String>();

		final int LIVE_MAX_COUNT = ServerConfig.getLiveMaxcount();
		// 优先直播的
		for (String userId : liveUsers) {
			if (sameUserId.contains(userId)) {
				continue;
			}
			RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
			if (roomInfo != null) {
				liveList.add(roomInfo);
			}
			sameUserId.add(userId);
			if (liveList.size() == LIVE_MAX_COUNT) {
				break;
			}
		}
		// 不够取推荐的
		if (liveList.size() < LIVE_MAX_COUNT && configs != null) {
			// 取推荐的
			for (MainView config : configs) {
				if (sameUserId.contains(String.valueOf(config.getUserId()))) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(config.getUserId(), users);
				if (roomInfo != null) {
					liveList.add(roomInfo);
				}
				sameUserId.add(String.valueOf(config.getUserId()));
				if (liveList.size() == LIVE_MAX_COUNT) {
					break;
				}
			}
		}
		// 不够取结束的
		if (liveList.size() < LIVE_MAX_COUNT) {
			// 取推荐的
			for (String userId : endUsers) {
				if (sameUserId.contains(userId)) {
					continue;
				}
				RoomInfoModel roomInfo = getNewRoomInfo(Long.parseLong(userId), users);
				if (roomInfo != null) {
					liveList.add(roomInfo);
				}
				sameUserId.add(userId);
				if (liveList.size() == LIVE_MAX_COUNT) {
					break;
				}
			}
		}
	}

	/**
	 * 得到roomInfo对象并缓存,如果有缓存利用,没有新建
	 * 
	 * @param userId
	 * @param users
	 * @return
	 */
	private RoomInfoModel getNewRoomInfo(long userId, Map<String, RoomInfoModel> users) {
		String key = String.valueOf(userId);
		if (!users.containsKey(key)) {
			RoomInfoModel roomInfo = getBaseRoomInfo(userId);

			if (roomInfo != null) {
				roomInfo.setUserCount(0);
				String count = String.valueOf(roomInfo.getUserId());
				Map<String, String> roomCount = getRoomCount();
				if (roomCount.containsKey(count)) {
					roomInfo.setUserCount(Integer.parseInt(roomCount.get(count)));
				}
				users.put(key, roomInfo);
			}
			return roomInfo;
		}
		return users.get(key);
	}

	/**
	 * 得到roomInfo
	 * 
	 * @param userId
	 * @return
	 */
	public RoomInfoModel getRoomInfo(long userId) {
		String key = String.valueOf(userId);
		// 首先获取缓存数据
		Map<String, RoomInfoModel> users = getUsers();
		if (!users.containsKey(key)) {
			RoomInfoModel roomInfo = getBaseRoomInfo(userId);

			if (roomInfo != null) {
				roomInfo.setUserCount(0);
				String count = String.valueOf(roomInfo.getUserId());

				Map<String, String> roomCount = getRoomCount();
				if (roomCount.containsKey(count)) {
					roomInfo.setUserCount(Integer.parseInt(roomCount.get(count)));
				}
			}
			return roomInfo;
		}
		return users.get(key);
	}

	private RoomInfoModel getBaseRoomInfo(long userId) {

		Map<String, String> userMap = redis.hgetAll(RedisConfig.USER_ROOM_PREF + userId);
		if (userMap != null && !userMap.isEmpty()) {
			// 查找用户
			RoomInfoModel roomInfo = new RoomInfoModel();
			roomInfo.setAccountType(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_ACCOUNT_TYPE), "0"));
			roomInfo.setExtId(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_EXT_ID), "0"));
			roomInfo.setIsLive(Utils.parseInt(userMap.get(RedisConfig.USER_ROOME_IS_LIVE)));
			// 如果在直播
			roomInfo.setLiveUrl(ServerConfig.getLiveURL(userId));
			roomInfo.setRoomPassword(Utils.parseString(userMap.get(RedisConfig.USER_ROOM_PASSWORD), ""));
			roomInfo.setRoomPaymentTypeId(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_PAYMENT_TYPE_ID), "0"));
			roomInfo.setRoomTitle(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_TITLE), ""));
			roomInfo.setStartedTime(Utils.parseLong(userMap.get(RedisConfig.USER_ROOME_STARTED_TIME)));
			roomInfo.setRoomTypeId(Utils.parseInt(userMap.get(RedisConfig.USER_ROOME_TYPE_ID)));

			roomInfo.setProfilePic(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_PROFILE_PIC), ""));
			roomInfo.setStarLevel(getUserStarLevel(userId));
			roomInfo.setUserAlias(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_USER_ALIAS), ""));
			roomInfo.setUserCount(Utils.parseInt(userMap.get(RedisConfig.USER_ROOME_USER_COUNT)));
			roomInfo.setUserId(userId);
			roomInfo.setUserPic(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_USER_PIC), ""));
			roomInfo.setUserTypeId(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_USER_TYPE_ID), "0"));
			roomInfo.setVjTypeId(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_VJ_TYPE_ID), ""));
			roomInfo.setVjSubtypeId(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_VJ_SUBTYPE_ID), ""));
			roomInfo.setRoomPic(Utils.parseString(userMap.get(RedisConfig.USER_ROOME_PIC), ""));
			roomInfo.setPayment(resourceSystem.getPayment(Utils.parseInt(roomInfo.getRoomPaymentTypeId())));
			roomInfo.setGiftCount(Utils.parseInt(userMap.get(RedisConfig.USER_ROOME_GIFT_COUNT)));
			return roomInfo;
		} else {

			UserInfo info = userSystem.getUserInfo(userId);

			if (info == null) {
				logger.error("用户id={}不存在", userId);
				return null;
			}
			RoomInfoModel roomInfo = new RoomInfoModel();

			roomInfo.setAccountType(info.getAccountType() + "");
			roomInfo.setExtId("0");
			roomInfo.setIsLive(0);
			roomInfo.setLiveUrl(ServerConfig.getLiveURL(userId));
			roomInfo.setProfilePic(info.getProfilePic());
			roomInfo.setRoomPassword("");
			roomInfo.setRoomPaymentTypeId("0");
			roomInfo.setRoomTitle("");
			roomInfo.setStarLevel(getUserStarLevel(userId));
			roomInfo.setStartedTime(0L);
			roomInfo.setUserAlias(info.getUserAlias());
			roomInfo.setUserCount(0);
			roomInfo.setUserId(userId);
			roomInfo.setUserPic(info.getUserPic());
			roomInfo.setUserTypeId(info.getUserTypeId() + "");
			roomInfo.setVjTypeId(info.getVjTypeId() + "");
			roomInfo.setVjSubtypeId(info.getVjSubtypeId() + "");

			roomInfo.setRoomTypeId(0);
			roomInfo.setRoomPic(info.getRoomPic());
			roomInfo.setPayment(0);
			roomInfo.setGiftCount(0);
			return roomInfo;
		}
	}

	/**
	 * 获取主播等级
	 * 
	 * @param userId
	 * @return
	 */
	private int getUserStarLevel(long userId) {

		String count = redis.get(RedisConfig.LIKES_COUNT + userId);
		if (count.equals("")) {
			return 0;
		}
		List<VjLevel> config = resourceSystem.getVjLevelConfigList();
		int num = Integer.parseInt(count);

		for (VjLevel v : config) {
			if (v.getMinCoin() >= num && num < v.getMaxCoin()) {
				return v.getLevel();
			}
		}
		return config.get(config.size() - 1).getLevel();
	}

	public List<RoomInfoModel> getDiscoverList(int vjTypeId, int page) {
		List<RoomInfoModel> all = getDiscoverByVjTypeList().get(vjTypeId);

		List<RoomInfoModel> getList = new ArrayList<RoomInfoModel>();

		int begin = ServerConfig.getPageMaxcount() * page;
		int end = begin + ServerConfig.getPageMaxcount() - 1;

		int size = all.size();

		if (begin >= ServerConfig.getDiscoverMaxcount() || size < (begin + 1)) {
			// 达到最大或者数量不足
			return getList;
		}
		end = Math.min(end, size);
		for (int i = begin; i < end; i++) {
			getList.add(all.get(i));
		}

		return getList;
	}

	public Map<Integer, List<RoomInfoModel>> getDiscoverByVjTypeList() {
		return discoverByVjTypeList;
	}

	public void setDiscoverByVjTypeList(Map<Integer, List<RoomInfoModel>> discoverByVjTypeList) {
		this.discoverByVjTypeList = discoverByVjTypeList;
	}

	public Map<Integer, List<RoomInfoModel>> getLiveByVjTypeList() {
		return liveByVjTypeList;
	}

	public List<RoomInfoModel> getLiveByVjTypeList(int vjTypeId) {
		return getLiveByVjTypeList().get(vjTypeId);
	}

	public void setLiveByVjTypeList(Map<Integer, List<RoomInfoModel>> liveByVjTypeList) {
		this.liveByVjTypeList = liveByVjTypeList;
	}

	public List<AdvanceVideoModel> getVideoList() {
		return videoList;
	}

	public void setVideoList(List<AdvanceVideoModel> videoList) {
		this.videoList = videoList;
	}

	public List<RoomInfoModel> getDorenList() {
		return dorenList;
	}

	public void setDorenList(List<RoomInfoModel> dorenList) {
		this.dorenList = dorenList;
	}

	public List<AdModel> getAdList() {
		return adList;
	}

	public void setAdList(List<AdModel> adList) {
		this.adList = adList;
	}

	public List<VjTypeModel> getVjTypeList() {
		return vjTypeList;
	}

	public void setVjTypeList(List<VjTypeModel> vjTypeList) {
		this.vjTypeList = vjTypeList;
	}

	public LinkedHashMap<Integer, List<RoomInfoModel>> getDiscoverShowList() {
		return discoverShowList;
	}

	public void setDiscoverShowList(LinkedHashMap<Integer, List<RoomInfoModel>> discoverShowList) {
		this.discoverShowList = discoverShowList;
	}

	public LinkedHashMap<String, List<RoomInfoModel>> getLiveShowList() {
		return liveShowList;
	}

	public void setLiveShowList(LinkedHashMap<String, List<RoomInfoModel>> liveShowList) {
		this.liveShowList = liveShowList;
	}

	public List<RoomInfoModel> getLiveList() {
		return liveList;
	}

	public void setLiveList(List<RoomInfoModel> liveList) {
		this.liveList = liveList;
	}

	private Map<String, RoomInfoModel> getUsers() {
		return users;
	}

	private void setUsers(Map<String, RoomInfoModel> users) {
		this.users = users;
	}

	private Map<String, String> getRoomCount() {
		return roomCount;
	}

	@SuppressWarnings("unchecked")
	private void setRoomCount(String roomCountStr) {
		Map<String, String> roomCount = new HashMap<String, String>();
		try {
			if (!StringUtils.isBlank(roomCountStr)) {
				roomCount = JSONObject.parseObject(roomCountStr, Map.class);
			}
		} catch (Exception e) {
		}

		this.roomCount = roomCount;
	}

}
